<template>
  <el-transfer
    class="transfer-wrap"
    ref="transfer"
    v-model="sortList"
    :data="transferData"
    :titles="titles"
    target-order="push"
    :props="transferProps"
    @left-check-change="updateLeftChecked"
    @right-check-change="updateRightChecked"
    @change="(_, direction, key) => $emit('change', _, direction, key)"
  >
    <span
      class="label-item"
      slot-scope="{ option }"
      draggable="!option.disabled"
      @dragstart="handleDragStart($event, option)"
    >
      {{ option[transferProps.label] }}
      <slot name="right-label" :sort-list="sortList" :option="option"></slot>
    </span>
    <el-button
      class="transfer-footer"
      type="primary"
      slot="right-footer"
      @click="confirmSelection"
      >提交</el-button
    >
  </el-transfer>
</template>

<script>
import Sortable from "sortablejs";
import { cloneDeep } from "lodash";

export default {
  name: "SelectionTransfer",
  props: {
    transferProps: {
      type: Object,
      default: () => ({
        key: "key",
        label: "label",
      }),
    },
    titles: {
      type: Array,
      default: () => ["隐藏列", "显示列"],
    },
    transferDataList: {
      type: Array,
      default: () => [],
    },

    defaultSelectionList: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      sortList: [],
      transferData: [],
      transferLeftCheckData: [],
      transferRightCheckData: [],
      draggingKey: "",
    };
  },
  watch: {
    transferDataList() {
      this.initializeTransferData();
      this.enableDragAndDrop();
    },
    defaultSelectionList() {
      this.initializeTransferData();
      this.enableDragAndDrop();
    },
  },
  methods: {
    initializeTransferData() {
      // 已选数据
      this.sortList = cloneDeep(this.defaultSelectionList);

      // 未选数据（从 transferDataList 中剔除已选数据）
      const selectedKeys = new Set(
        this.sortList.map((item) => item[this.transferProps.key]),
      );
      this.transferData = this.transferDataList.filter(
        (item) => !selectedKeys.has(item[this.transferProps.key]),
      );
    },
    enableDragAndDrop() {
      this.$nextTick(() => {
        const { leftPanel, rightPanel } = this.getPanels();
        console.log(leftPanel, rightPanel);
        this.initSortable(rightPanel, "sortList");
        this.initSortable(leftPanel, "transferData");
        this.setupDragEvents(leftPanel, rightPanel);
      });
    },
    getPanels() {
      const transfer = this.$refs.transfer.$el;
      const [leftPanel, rightPanel] =
        transfer.getElementsByClassName("el-transfer-panel");
      return {
        leftPanel: leftPanel.getElementsByClassName(
          "el-transfer-panel__body",
        )[0],
        rightPanel: rightPanel.getElementsByClassName(
          "el-transfer-panel__body",
        )[0],
      };
    },
    initSortable(panel, targetArray) {
      const listElement = panel.getElementsByClassName(
        "el-transfer-panel__list",
      )[0];
      Sortable.create(listElement, {
        onEnd: (evt) => this.handleSort(evt, targetArray),
      });
    },
    setupDragEvents(leftPanel, rightPanel) {
      leftPanel.ondragover = (ev) => ev.preventDefault();
      rightPanel.ondragover = (ev) => ev.preventDefault();
      leftPanel.ondrop = (ev) => this.handleDrop(ev, "left");
      rightPanel.ondrop = (ev) => this.handleDrop(ev, "right");
    },
    handleSort(evt, targetArray) {
      const { oldIndex, newIndex } = evt;
      const array = this[targetArray];

      const [movedItem] = array.splice(oldIndex, 1);
      if (movedItem) {
        array.splice(newIndex, 0, movedItem);
      }

      this[targetArray] = [...array];
    },
    handleDrop(evt, targetArray) {
      const { oldIndex, newIndex } = evt;
      const array = this[targetArray];

      const [movedItem] = array.splice(oldIndex, 1);
      if (movedItem) {
        array.splice(newIndex, 0, movedItem);
      }

      this[targetArray] = [...array];
    },

    handleDragStart(ev, option) {
      this.draggingKey = option[this.transferProps.key];
    },
    updateLeftChecked(val) {
      this.transferLeftCheckData = [...val];
    },
    updateRightChecked(val) {
      this.transferRightCheckData = [...val];
    },
    // handleChange(_, direction, labelId) {
    //   const item = this.transferData.find((item) => item.labelId === labelId);
    //   if (direction === "right") {
    //
    //   }
    //   console.log(direction, labelId, this.sortList, this.transferData);
    // },
    confirmSelection() {
      if (!this.sortList.length) {
        this.$message.warning("未选中任何需要显示的数据");
        return;
      }
      this.$emit("confirm", this.sortList);
    },
  },
};
</script>

<style lang="scss" scoped>
.transfer-wrap {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 100%;

  /deep/ .el-transfer-panel {
    flex: 1;
    height: 100%;

    .el-transfer-panel__body {
      height: calc(100% - 40px);

      &.is-with-footer {
        height: calc(100% - 80px);
      }

      .el-transfer-panel__list {
        height: 100%;
      }
    }
  }

  ///deep/ .el-transfer__buttons {
  //  .el-button {
  //    &:last-child {
  //      display: none;
  //    }
  //  }
  //}

  .transfer-footer {
    margin-left: 20px;
    padding: 6px 5px;
    width: 80px;
  }
}
</style>
